<template>
	<view class="content">
		<image class="logo" src="/static/logo.png"></image>
		<view class="text-area">
			<text class="title">{{title}}</text>
		</view>
		<button type="primary" @click="startUpload">上传</button>
		<button type="primary" @click="startUpdate">更新</button>
		<button type="warn" @click="deleteAllData">删除全部</button>
        <button type="default" @click="queryStats">查询</button>
        <button type="default" @click="querySpecial">查询指定菜单</button>
        <button type="warn" @click="deleteAfter">删除指定时间后</button>
	</view>
</template>

<script>
	export default {
	data() {
		return {
				title: 'Hello',
				jsonFilesCache: null,
				imgFilesCache: null
		}
	},
		onLoad() {

		},
		methods: {
			// 仅保留 H5：目录选择 + 客户端直传（分两次点击触发）
			async startUpload() {
			  try {
			    // 第一次点击：选择 JSON 目录并缓存
			    if (!this.jsonFilesCache) {
			      const jsonFiles = await this.chooseDirectory(['.json']);
			      if (!jsonFiles || jsonFiles.length === 0) return;
			      this.jsonFilesCache = jsonFiles;
			      uni.showToast({ title: '已选JSON目录，请再点上传选图片目录', icon: 'none' });
			      return;
			    }

			    // 第二次点击：选择图片目录并缓存，然后开始上传
			    if (!this.imgFilesCache) {
			      const imgFiles = await this.chooseDirectory(['.jpg', '.jpeg', '.png', '.gif', '.webp']);
			      if (!imgFiles || imgFiles.length === 0) return;
			      this.imgFilesCache = imgFiles;
			    }


			    uni.showLoading({ title: '开始上传数据...' });
				//搜集所有json文件
			    const jsonByCat = new Map();
			    for (const f of this.jsonFilesCache) {
			      const name = f.name.toLowerCase();
			      if (name.endsWith('.json')) jsonByCat.set(name.replace('.json',''), f);
			    }
				//搜集所有图片.jpg,并分目录存储
			    const imgsByCat = new Map();
			    for (const f of this.imgFilesCache) {
			      const rel = (f.webkitRelativePath || '').split('/');
			      const cat = rel.length > 2 ? rel[1].toLowerCase() : '';
			      if (!cat) continue;
			      if (!imgsByCat.has(cat)) imgsByCat.set(cat, []);
			      imgsByCat.get(cat).push(f);
			    }
				//打印一下jsonByCat和imgsByCat分别由多少条数据
				// console.log('jsonByCat:', jsonByCat);
				// console.log('imgsByCat:', imgsByCat);

				let totalImgCount = 0;
			    let totalRecords = 0;
			    for (const [category, jsonFile] of jsonByCat.entries()) {
			      const jsonText = await jsonFile.text();
			      const jsonData = JSON.parse(jsonText);
			      const required = new Set(Array.isArray(jsonData) ? jsonData.map(i => i.img).filter(Boolean) : []);
			      const files = imgsByCat.get(category) || [];
			      const fileIdMap = {};
			      // 按需分批上传, json和img里都有的图片
			      const need = files.filter(f => required.has(f.name));

			      for (let i = 0; i < need.length; i += 50) {
			        const batch = need.slice(i, i + 50);
			        const tasks = batch.map(file => {
			          // H5端：使用 Blob URL 字符串作为 filePath，并声明 fileType
			          const blobUrl = URL.createObjectURL(file);
			          return uniCloud.uploadFile({
			            cloudPath: `dishes/${category}/${file.name}`,
			            filePath: blobUrl,
			            fileType: 'image'
			          }).then(res => {
						// console.log('上传成功:', file.name);
			            const fid = res.fileID || res.fileId;
			            if (fid) fileIdMap[file.name] = fid;
			          }).catch(err => console.error(`[${category}] 上传失败: ${file.name}`, err))
			            .finally(() => URL.revokeObjectURL(blobUrl));
			        });
			        await Promise.allSettled(tasks);
			        console.log(`${category} 类 已上传图片: ${Math.min(i + batch.length, need.length)}/${need.length}`);
			        await new Promise(r => setTimeout(r, 300));
			      }
				  totalImgCount += Object.keys(fileIdMap).length;
				  console.log(`类别 ${category} 共需上传 ${need.length} 张图片，成功 ${Object.keys(fileIdMap).length}`);

			      const records = (jsonData || []).map(item => ({
			        chineseName: item.chineseName,
			        dishName: item.dishName,
			        dishIngredient: item.dishIngredient,
			        category: category,
			        img: item.img && fileIdMap[item.img] ? fileIdMap[item.img] : `dishes/${category}/${item.img}`,
			        createDate: Date.now()
			      }));
				  const insertRes = await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'insert-records', records } });
				  const insertCount = (insertRes.result && insertRes.result.count) ? insertRes.result.count : records.length;
				  totalRecords += insertCount 
				  console.log(`类别 ${category} 共需上传 ${jsonData.length} 条dishes记录 成功 ${insertCount} `);
			      console.log(`完成类别 ${category}，累计入库 图片: ${totalImgCount} 记录: ${totalRecords}`);
			      await new Promise(r => setTimeout(r, 500));
			    }

			    uni.hideLoading();
			    uni.showToast({ title: `上传完成 图片:(${totalImgCount}) 记录: (${totalRecords})`, icon: 'success' });
			    // 清理缓存，便于下一次上传
			    this.jsonFilesCache = null;
			    this.imgFilesCache = null;
			  } catch (error) {
			    uni.hideLoading();
			    console.error('上传失败:', error);
			    uni.showToast({ title: '上传失败', icon: 'error' });
			  }
			},
			// 仅保留 H5：目录选择 + 客户端直传（分两次点击触发）
			async startUpdate() {
			  try {
			    // 第一次点击：选择 JSON 目录并缓存
			    if (!this.jsonFilesCache) {
			      const jsonFiles = await this.chooseDirectory(['.json']);
			      if (!jsonFiles || jsonFiles.length === 0) return;
			      this.jsonFilesCache = jsonFiles;
			      uni.showToast({ title: '已选JSON目录，请再点上传选图片目录', icon: 'none' });
			      return;
			    }

			    // 第二次点击：选择图片目录并缓存，然后开始上传
			    if (!this.imgFilesCache) {
			      const imgFiles = await this.chooseDirectory(['.jpg', '.jpeg', '.png', '.gif', '.webp']);
			      if (!imgFiles || imgFiles.length === 0) return;
			      this.imgFilesCache = imgFiles;
			    }


			    uni.showLoading({ title: '开始更新图片...' });
				//搜集所有json文件
			    const jsonByCat = new Map();
			    for (const f of this.jsonFilesCache) {
			      const name = f.name.toLowerCase();
			      if (name.endsWith('.json')) jsonByCat.set(name.replace('.json',''), f);
			    }
				//搜集所有图片.jpg,并分目录存储
			    const imgsByCat = new Map();
			    for (const f of this.imgFilesCache) {
			      const rel = (f.webkitRelativePath || '').split('/');
			      const cat = rel.length > 2 ? rel[1].toLowerCase() : '';
			      if (!cat) continue;
			      if (!imgsByCat.has(cat)) imgsByCat.set(cat, []);
			      imgsByCat.get(cat).push(f);
			    }
				//打印一下jsonByCat和imgsByCat分别由多少条数据
				// console.log('jsonByCat:', jsonByCat);
				// console.log('imgsByCat:', imgsByCat);

				// 仅修复缺失图片：遍历数据库当前类别的记录，存在即跳过，不存在才上传并更新
				let totalProcessed = 0;
				let totalFixed = 0;
				let totalSkipped = 0;
				let totalMissingLocal = 0;
				for (const [category, jsonFile] of jsonByCat.entries()) {
				  const files = imgsByCat.get(category) || [];
				  let cursor = 0;
				  const PAGE_SIZE = 200;
				  const CHECK_BATCH = 30;
				  while (true) {
				    // 拉取一页该类别的记录（仅必要字段）
				    const resPage = await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'list-dishes', category, cursor, pageSize: PAGE_SIZE } });
				    const resultPage = resPage && resPage.result ? resPage.result : resPage;
				    const items = Array.isArray(resultPage.items) ? resultPage.items : [];
				    if (items.length === 0) break;
				    totalProcessed += items.length;

				    // 收集本页需要校验的 fileID 以及无法校验的待修复项
				    const idsToCheck = [];
				    const recByFid = new Map();
				    const needReupload = [];
				    for (const rec of items) {
				      const v = rec.img;
				      let fid = null;
				      if (typeof v === 'string' && /^cloud:\/\//.test(v)) fid = v;
				      const filename = typeof v === 'string' ? v.split('/').pop() : (fid ? String(fid).split('/').pop() : null);
				      if (fid) { idsToCheck.push(fid); recByFid.set(fid, { rec, filename }); }
				      else { needReupload.push({ rec, filename }); }
				    }

				    // 批量校验本页 fileID 是否真实存在
				    const missingFids = new Set();
					const okFids = new Set();
				    for (let i = 0; i < idsToCheck.length; i += CHECK_BATCH) {
				      const batch = idsToCheck.slice(i, i + CHECK_BATCH);
				      try {
				        const r = await uniCloud.getTempFileURL({ fileList: batch });
				        const list = (r && Array.isArray(r.fileList)) ? r.fileList
				          : (r && Array.isArray(r.urls)) ? r.urls
				          : (r && Array.isArray(r.tempFiles)) ? r.tempFiles
				          : [];
				        for (let j = 0; j < list.length; j++) {
				          const it = list[j];
				          const ok = (typeof it.tempFileURL === 'string' && it.tempFileURL)
				            || (typeof it.download_url === 'string' && it.download_url)
				            || (typeof it.url === 'string' && it.url)
				            || (typeof it.code === 'number' && it.code === 0)
				            || it.status === 0 || it.status === 'SUCCESS';
				          const fid = typeof it.fileID === 'string' ? it.fileID
				            : typeof it.fileId === 'string' ? it.fileId
				            : batch[j];
				          if (!ok) missingFids.add(fid);
				          else okFids.add(fid);
				        }
				      } catch (e) {
				        console.error('批量校验失败', e);
				      }
				      await new Promise(r => setTimeout(r, 100));
				    }

				    // 将“有 fileID 但不存在”的记录加入待修复队列
				    for (const fid of missingFids) {
				      const info = recByFid.get(fid);
				      if (info) needReupload.push(info);
				    }

				    // 执行修复：找到本地图片，上传并更新记录 img 为新的 fileID
				    for (const item of needReupload) {
				      const fileName = item.filename;
				      const file = files.find(f => f.name === fileName);
				      if (!file) { totalMissingLocal += 1; continue; }
				      const blobUrl = URL.createObjectURL(file);
				      try {
				        const up = await uniCloud.uploadFile({ cloudPath: `dishes/${category}/${file.name}`, filePath: blobUrl, fileType: 'image' });
				        const newFid = up.fileID || up.fileId;
				        if (newFid) {
				          await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'update-image-by-id', id: item.rec._id, img: newFid } });
				          totalFixed += 1;
				        }
				      } catch (err) {
				        console.error(`[${category}] 修复上传失败: ${fileName}`, err);
				      } finally {
				        URL.revokeObjectURL(blobUrl);
				      }
				      await new Promise(r => setTimeout(r, 150));
				    }

				    // 本页跳过数量 = 已有且存在的 fileID 数量
				    totalSkipped += Math.max(idsToCheck.length - missingFids.size, 0);
				    cursor = (typeof resultPage.nextCursor === 'number') ? resultPage.nextCursor : (cursor + items.length);
				    if (resultPage.hasMore !== true) break;
				    await new Promise(r => setTimeout(r, 300));
				  }
				  console.log(`完成类别 ${category}：处理 ${totalProcessed}，修复 ${totalFixed}，跳过 ${totalSkipped}，缺少本地图片 ${totalMissingLocal}`);
				}

				uni.hideLoading();
				uni.showToast({ title: `修复完成 处理:${totalProcessed} 修复:${totalFixed} 跳过:${totalSkipped} 缺图:${totalMissingLocal}`, icon: 'success' });
			    // 清理缓存，便于下一次上传
			    this.jsonFilesCache = null;
			    this.imgFilesCache = null;
			  } catch (error) {
			    uni.hideLoading();
			    console.error('上传失败:', error);
			    uni.showToast({ title: '上传失败', icon: 'error' });
			  }
			},

			// H5：选择目录，返回 File[]
			chooseDirectory(acceptExts = ['.json']) {
			  return new Promise(resolve => {
			    const input = document.createElement('input');
			    input.type = 'file';
			    input.setAttribute('webkitdirectory', '');
			    input.multiple = true;
			    input.style.display = 'none';
			    document.body.appendChild(input);
			    input.addEventListener('change', () => {
			      const files = Array.from(input.files || []);
			      const exts = acceptExts.map(e => e.toLowerCase());
			      const filtered = files.filter(f => exts.some(e => f.name.toLowerCase().endsWith(e)));
			      resolve(filtered);
			      document.body.removeChild(input);
			    });
			    input.click();
			  });
			},

			// 删除 dishes 表和云存储中的所有数据
			async deleteAllData() {
			  try {
			    const confirmRes = await new Promise((resolve) => {
			      uni.showModal({
			        title: '确认删除',
			        content: '此操作将删除 dishes 表和云存储中的所有数据，是否继续？',
			        success: (res) => resolve(res)
			      });
			    });

			    if (!confirmRes.confirm) {
			      return;
			    }

			    uni.showLoading({ title: '正在删除...' });
			    let result;
			    //   const uploadManager = uniCloud.importObject('upload-manager');
			    //   result = await uploadManager.deleteAll();
				const res = await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'delete-all' } });
				result = res && res.result ? res.result : res;

			    uni.hideLoading();
			    console.log('删除完成:', result);
			    uni.showToast({ title: '删除完成', icon: 'success' });
			  } catch (error) {
			    uni.hideLoading();
			    console.error('删除失败:', error);
			    uni.showToast({ title: '删除失败', icon: 'error' });
			  }
			},

			// 分页查询记录总数与“真实存在”的唯一图片数量（前端去重汇总）
			async queryStats() {
			  try {
			    uni.showLoading({ title: '查询中...' });
			    let cursor = 0;
			    const pageSize = 100; // 每页条数，适当调小避免超时
			    const checkBatch = 10; // 单次校验图片存在的批大小
			    let totalRecords = 0;
				let totalImages = 0;

				//检查dishes表记录总数
				const resDishes = await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'querydishes', pageSize } });
				const resultDishes = resDishes && resDishes.result ? resDishes.result : resDishes;
				if (typeof resultDishes.totalRecords === 'number') {
					totalRecords = resultDishes.totalRecords;
				}
				console.log('dishes表记录总数:', totalRecords);

				//检查dishes表中存在的图片
				while(true) {
					const resImgs = await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'queryimgs', cursor, pageSize, checkBatch } });
					const resultImgs = resImgs && resImgs.result ? resImgs.result : resImgs;
					if (typeof resultImgs.validImages === 'number') {
						totalImages += resultImgs.validImages;
					}
					cursor = (resultImgs && typeof resultImgs.nextCursor === 'number') ? resultImgs.nextCursor : cursor;

					uni.showLoading({ title: `查询中...(${totalImages})` });
					if (!resultImgs || resultImgs.hasMore !== true) break;
					await new Promise(r => setTimeout(r, 200));
				}

				console.log('dishes表中存在的图片数量:', totalImages);

			    uni.hideLoading();
			    uni.showToast({ title: `记录: ${totalRecords ?? '未知'}，图片: ${totalImages}` , icon: 'none' });
			    console.log('统计结果:', { success: true, totalRecords, totalImages });
			  } catch (error) {
			    uni.hideLoading();
			    console.error('查询失败:', error);
			    uni.showToast({ title: '查询失败', icon: 'error' });
			  }
			},

			// 查询指定中文菜单 specialDishes 的完整记录，并打印输出
			async querySpecial() {
			  try {
			    const specialDishes = ["蝴蝶面"]; // 指定列表
			    uni.showLoading({ title: '查询中...' });
			    const res = await uniCloud.callFunction({
			      name: 'batch-upload',
			      data: { action: 'query-special', specialDishes }
			    });
			    const result = res && res.result ? res.result : res;
			    const items = Array.isArray(result && result.items) ? result.items : [];
			    uni.hideLoading();
			    console.log('specialDishes 查询结果（完整记录）:', items);
			    uni.showModal({
			      title: '查询完成',
			      content: `共 ${items.length} 条\n` +
			        JSON.stringify(items, null, 2).slice(0, 900),
			      showCancel: false
			    });
			  } catch (error) {
			    uni.hideLoading();
			    console.error('查询指定菜单失败:', error);
			    uni.showToast({ title: '查询失败', icon: 'error' });
			  }
			},

			// 删除 createDate/createTime 大于指定时间戳的记录与对应图片
			async deleteAfter() {
			  try {
			    const cutoffTs = 1764056223259; // 指定删除阈值（毫秒时间戳）
			    const confirmRes = await new Promise((resolve) => {
			      uni.showModal({
			        title: '确认删除',
			        content: `将删除 createDate/createTime > ${cutoffTs} 的所有记录与图片，是否继续？`,
			        success: (res) => resolve(res)
			      });
			    });
			    if (!confirmRes.confirm) return;

			    uni.showLoading({ title: '正在删除...' });
			    let totalFiles = 0;
			    let totalRecords = 0;
			    let loop = 0;
			    while (true) {
			      const res = await uniCloud.callFunction({ name: 'batch-upload', data: { action: 'delete-after', cutoffTs, pageSize: 50 } });
			      const result = res && res.result ? res.result : res;
			      totalFiles += (result && result.deletedFiles) || 0;
			      totalRecords += (result && result.deletedRecords) || 0;
			      loop++;
			      uni.showLoading({ title: `删除中...(${loop})` });
			      if (!result || result.hasMore !== true) break;
			      await new Promise(r => setTimeout(r, 200));
			    }
			    uni.hideLoading();
			    console.log('按时间删除完成: 图片', totalFiles, '记录', totalRecords);
			    uni.showToast({ title: `删除 图片:${totalFiles}，记录:${totalRecords}` , icon: 'success' });
			  } catch (error) {
			    uni.hideLoading();
			    console.error('按时间删除失败:', error);
			    uni.showToast({ title: '删除失败', icon: 'error' });
			  }
			}

		}
	}
</script>

<style>
	.content {
		display: flex;
		flex-direction: column;
		align-items: center;
		justify-content: center;
	}

	.logo {
		height: 200rpx;
		width: 200rpx;
		margin-top: 200rpx;
		margin-left: auto;
		margin-right: auto;
		margin-bottom: 50rpx;
	}

	.text-area {
		display: flex;
		justify-content: center;
	}

	.title {
		font-size: 36rpx;
		color: #8f8f94;
	}
</style>
